package main

import (
	"fmt"
	"time"
)

// 模拟量数据结构
type AnalogData struct {
	ReturnCode    byte
	AnalogValues  [23]int16 // 23个模拟量数据字段
}

// 模拟量数据字段的编码
func encodeAnalogData(data AnalogData) []byte {
	var encodedData []byte

	// 遍历模拟量数据字段，按照表10的格式编码
	for _, value := range data.AnalogValues {
		encodedData = append(encodedData, byte(value>>8), byte(value&0xFF))
	}

	return encodedData
}

// 校验和计算函数（CHKSUM）
func calculateChecksum(data []byte) []byte {
	var sum int32
	for _, b := range data {
		sum += int32(b)
	}
	checksum := sum % 65536
	checksum = ^checksum + 1
	return []byte{byte(checksum >> 8), byte(checksum & 0xFF)}
}

// 构建获取模拟量数据命令帧
func buildGetAnalogDataCommand() []byte {
	soi := []byte{0x7E}    // SOI
	ver := []byte{0x21}    // VER
	adr := []byte{0x01}    // ADR
	cid1 := []byte{0x60}   // CID1: 设备类型 - 分散空调
	cid2 := []byte{0x42}   // CID2: 获取模拟量数据命令
	length := []byte{0x00, 0x00} // LENGTH（LENID 为 0）
	checksum := calculateChecksum(append(soi, append(ver, append(adr, append(cid1, append(cid2, length...)...)...)...)...)
	eoi := []byte{0x0D}    // EOI

	// 拼接完整的命令帧
	commandFrame := append(soi, append(ver, append(adr, append(cid1, append(cid2, append(length, append(checksum, eoi...)...)...)...)...)...)
	return commandFrame
}

// 构建响应帧
func buildAnalogDataResponse(data AnalogData) []byte {
	soi := []byte{0x7E}    // SOI
	ver := []byte{0x21}    // VER
	adr := []byte{0x01}    // ADR
	cid1 := []byte{0x60}   // CID1: 设备类型 - 分散空调
	rtc := []byte{data.ReturnCode} // RTN: 返回码
	encodedData := encodeAnalogData(data) // DATA INFO
	length := []byte{0x00, 0x92} // LENGTH (LENID=92)
	checksum := calculateChecksum(append(soi, append(ver, append(adr, append(cid1, append(rtc, append(length, append(encodedData, eoi...)...)...)...)...)...)
	eoi := []byte{0x0D}    // EOI

	// 拼接完整的响应帧
	responseFrame := append(soi, append(ver, append(adr, append(cid1, append(rtc, append(length, append(encodedData, append(checksum, eoi...)...)...)...)...)...)
	return responseFrame
}

func main() {
	// 示例：构建获取模拟量数据命令
	commandFrame := buildGetAnalogDataCommand()
	fmt.Printf("获取模拟量数据命令帧: %X\n", commandFrame)

	// 示例：构建响应帧，包含模拟量数据
	analogData := AnalogData{
		ReturnCode: 0x00,  // 正常返回
		AnalogValues: [23]int16{
			240, 30, 235, 235, 240, 0, 50, 250, 245, 250, 240, 30, 30, 30, 30,
			30, 30, 120, 120, 110, 110, 500, 600,
		},
	}
	responseFrame := buildAnalogDataResponse(analogData)
	fmt.Printf("模拟量数据响应帧: %X\n", responseFrame)
}
